﻿using Zo.Queues;

namespace Zo.Events.Core
{
    /// <summary>
    /// 事件队列。
    /// </summary>
    internal abstract class EventQueue
    {
        /// <summary>
        /// 邮件条数。
        /// </summary>
        public abstract int Count { get; }

        /// <summary>
        /// 入队。
        /// </summary>
        /// <param name="envelope">消息。</param>
        public abstract void Enqueue(EventEnvelope envelope);

        /// <summary>
        /// 出队。
        /// </summary>
        /// <returns>消息。</returns>
        public abstract EventEnvelope Dequeue();
    }

    /// <summary>
    /// 线程安全邮箱。
    /// </summary>
    internal sealed class ConcurrentEventQueue : EventQueue
    {
        /// <summary>
        /// 队列。
        /// </summary>
        private readonly MonoConcurrentQueue<EventEnvelope> _messageQueue = new MonoConcurrentQueue<EventEnvelope>();

        /// <summary>
        /// 消息数。
        /// </summary>
        public override int Count => _messageQueue.Count;

        /// <summary>
        /// 入队。
        /// </summary>
        /// <param name="envelope">消息。</param>
        public override void Enqueue(EventEnvelope envelope)
        {
            _messageQueue.Enqueue(envelope);
        }

        /// <inheritdoc />
        /// <summary>
        /// 出队。
        /// </summary>
        /// <returns>消息。</returns>
        public override EventEnvelope Dequeue()
        {
            _messageQueue.TryDequeue(out var envelope);

            return envelope;
        }
    }
}